import java.util.ArrayList;
import java.util.TreeMap;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
/**
 * 
 * @author Adam and Terry
 *
 */
public class Region {
	TreeMap<String, Road> roads;
	private String filename;
	private TreeMap<String, Area> city;
	private TreeMap<String, Rail> rail;
	private TreeMap<String, Road> road;
	private TreeMap<String, State> state;
	private TreeMap<String, Point> point; 
	private ArrayList<Point> points; 
	
	/**
	 * Region Constructor 
	 * @param filename
	 */
	
	public Region(String filename)
	{
		this.filename = filename;
		points = new ArrayList<Point>();
		city = new TreeMap<String, Area>(); 
		rail = new TreeMap<String, Rail>(); 
		road = new TreeMap<String, Road>(); 
		state = new TreeMap<String, State>(); 
		point = new TreeMap<String, Point>(); 
	}
	
	/**
	 * Clear all the points from the arraylist after save 
	 */
	
	public void clearList()
	{
		this.points.removeAll(points);
	}
	
	/**
	 * 
	 */
	public int getArrayListSize()
	{
		return this.points.size();
	}
	
	/**
	 * 
	 * @return the string values from the arraylist and tree map 
	 */
	public String arrayListToString()
	{
		String s = "";
		
		for (Point p : point.values())
		{
			s = s + p.toString() + "end\n";
		}

		for(Point p: points) {
			s = s + p.toString() + "end\n";
		}
		return s;
	}
	
	/**
	 * 
	 * @param point
	 */
	public void addPointObject(Point point)
	{
		this.points.add(point);
	}
	
	/**
	 * 
	 * @return city treemap 
	 */
	public TreeMap<String, Area> getArea()
	{
		return this.city;
	}
	
	/**
	 * 
	 * @return rail treemap 
	 */
	public TreeMap<String, Rail> getRail()
	{
		return this.rail;
	}
	
	
	
	/**
	 * 
	 * @return road treemap 
	 */
	
	public TreeMap<String, Road> getRoad()
	{
		return this.road;
	}
	
	/**
	 * 
	 * @return state treemap 
	 */
	
	public TreeMap<String, State> getState()
	{
		return this.state;
	}
	
	/**
	 * 
	 * @return point treemap 
	 */
	public TreeMap<String, Point> getPoint()
	{
		return this.point;
	}
	
	/**
	 * load all the files from the scenario.scn file 
	 */
	public void loadFromFile()
	{
		if(filename != null){
		
		try{
			  FileInputStream fstream = new FileInputStream(filename);
			  DataInputStream in = new DataInputStream(fstream);
			  BufferedReader br = new BufferedReader(new InputStreamReader(in));
			  String strLine;
			  
			  while ((strLine = br.readLine()) != null)   {
				  String[] filetypes = strLine.split(",");
				  
				  if(filetypes[2].contains("|")){
					  filetypes[2] = "\\" +filetypes[2];
				  }
				  
				  if(filetypes.length == 3){
					  readFile(filetypes[0].trim(),filetypes[1].trim(), filetypes[2].trim());
				  }
			  }
			  in.close();
		   }
		   catch (Exception e)
		   {//Catch exception if any
			  System.err.println("Error: " + e.getMessage());
		   }
		   
		}
		  
	}
	
	/**
	 * 
	 * @param classtype
	 * @param file
	 * @param delimiter
	 * @throws IOException
	 */

	private void readFile(String classtype, String file, String delimiter) throws IOException {
		
			LineNumberReader in = new LineNumberReader(new FileReader(file));
			
			if(in.read() != -1){
					
			String stateName = in.readLine().trim();
			while (!stateName.equalsIgnoreCase("finalend")) {
				
				if(classtype.equalsIgnoreCase("State")){
					State r = new State(stateName, delimiter);
					r.read(in, stateName);
					state.put(r.getName(), r);
				}
				else if(classtype.equalsIgnoreCase("Area"))
				{
					Area r = new Area(stateName, delimiter);
					r.read(in, stateName);
					city.put(r.getName(), r);
				}
				else if(classtype.equalsIgnoreCase("Road"))
				{
					Road r = new Road(stateName, delimiter);
					r.read(in, stateName);
					road.put(r.getName(), r);
				}
				else if(classtype.equalsIgnoreCase("Rail")){
					Rail r = new Rail(stateName, delimiter);
					r.read(in, stateName);
					rail.put(r.getName(), r);
				}
				else if(classtype.equalsIgnoreCase("Point")){
				
					Point r = new Point(stateName, delimiter);
					r.read(in, stateName);
					point.put(r.getName(), r);
				}
				else
				{
					// do nothing 
				}
			
				stateName = in.readLine().trim();
			}
			
		}
	}
}
	
